<?php
// +----------------------------------------------------------------------
// | Author: July
// +----------------------------------------------------------------------
// | 创建时间: 2023-12-27 20:39:42
// +----------------------------------------------------------------------
// | 管理员角色控制器
// +----------------------------------------------------------------------

namespace july\julyadmin\admin\controller;

use july\julyadmin\builder\traits\HasBuilder;
use july\julyadmin\common\logic\AdminRoleLogic;
use july\julyadmin\common\model\AdminRole as AdminRoleModel;
use july\julyadmin\common\model\AdminRoleList as AdminRoleListModel;
use july\julyadmin\common\model\Menu as MenuModel;

class AdminRole extends Common
{
    use HasBuilder;

    //不需要登录验证的控制器和方法，如：['index']
    protected $noNeedLogin = [];
    //不需要权限验证的控制器和方法，如：['index']
    protected $noPermissionAuth = [];

    public function __construct()
    {
        //重新初始化父类
        parent::initialize();
        //数据模型
        $this->dataModel = new AdminRoleModel();
        //join关联查询的表信息如，['category'=>'inner','comment'=>'left']
        $this->relationWithJoins = [];
        //with预查询关联表信息，如category,comment
        $this->relationWiths = [];
        //页面标题
        $this->pageTitle = '角色管理';
        //允许表格行内编辑的字段,如name,sex
        $this->allowRowEditField = ['name', 'description', 'sort', 'disabled'];
        //不允许删除的主键数组，如1,2,3
        $this->noDeletePrimarykeys = [1];
        //不允许编辑的主键数组，如1,2,3
        $this->noEditPrimarykeys = [1];
        //不允许禁用的主键数组，如1,2,3
        $this->noDisabledPrimarykeys = [1];
        //下拉join关联查询的表信息如，['category'=>'inner','comment'=>'left']
        $this->selectRelationWithJoins = [];
        //下拉with预查询关联表信息，如category,comment
        $this->selectRelationWiths = [];
        //下拉列表默认查询条件，如 [['disabled', '=', 1]]，如果有配置了$this->selectRelationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin.
        $this->selectWhere = [];
        //下拉列表模糊查询字段,如 'name|title'，如果有配置了$this->selectRelationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin，当前表可以不加
        $this->selectSearch = 'name';
        //下拉列表默认 Text 字段 如 '{id}#{nickname}'或者'id:{id}-名称:{name}'，如果有配置了$this->selectRelationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin，当前表可以不加
        $this->selectTextField = '{id}#{name}';
        //下拉默认id字段,如：id
        $this->selectIdField = 'id';
        //下拉列表查询时的字段，如：id,name，如果有配置了$this->selectRelationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin.，当前表可以不加
        $this->selectFields = 'id,name';
        //下拉列表父id字段，如：parent_id，如果有配置了$this->selectRelationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin.
        $this->selectParentId = 'parent_id';
        //下拉列表查询第一层数据列表条件，如[['parent_id','=',0]],当表格为treeTable的时候，意味着你要输出的数据也会是树形的，这个时候首次查询最父层的数据列表可能需要传入这个参数，如果有配置了$this->SelectRelationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin.
        $this->selectOneParentWhere = [];
        //下拉列表查询排序，如果有配置了$this->selectRelationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin.
        $this->selectOrder = '';
        //列表排序，如果有配置了$this->relationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin.
        $this->sort = 'id desc';
        //父id字段名称，如parent_id,当表格为treeTable的时候，意味着你要输出的数据也会是树形的，这个时候需要指定父级字段名称，如果有配置了$this->selectRelationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin.，根据实际需求修改
        $this->parentField = '';
        //查询第一层数据列表条件，如[['parent_id','=',0]],当表格为treeTable的时候，意味着你要输出的数据也会是树形的，这个时候首次查询最父层的数据列表可能需要传入这个参数，如果有配置了$this->relationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如admin.
        $this->oneParentWhere = [];
        //表格类型,table,treeTable
        $this->tableType = 'table';
        //树形表格分组字段，比如name，那么展开和搜索箭头就会在name这一列显示，当表格为treeTable的时候会用到
        $this->treeTableGroupField = '';
        //需要合计的字段，如['显示在哪个字段','显示哪个字段的值']，如果有配置了$this->selectRelationWithJoins，这里就需要注意了，排序字段需要带上表名加一个点，如['id'=>'admin.sex','money'=>admin.money']
        $this->totalRow = [];
        //设置主键
        $this->pk = 'id';
    }

    /**
     * 设置当前页面
     * @Author   July
     * @DateTime 2024-01-13T19:41:56+0800
     * @param    $table 表格
     */
    protected function buildPage(&$table = [])
    {
        //表格工具栏
        $table->getToolbar()
            ->addBtn(true, '添加', '98%', '98%')
            ->disabledBtn()
            ->deleteBtn()
            ->refreshBtn();
        //表格数据
        $table->showCheckbox();
        $table->show('id', 'ID')->width(100)->sort(true);
        $table->show('name', '角色名称')->edit('text')->width(180)->sort(true);
        $table->show('disabled', '禁用状态', 'switchBtn')->edit('switchBtn')->width(120)->sort(true);
        $table->show('sort', '排序')->width(100)->sort(true);
        $table->show('description', '角色描述')->edit('textarea')->width(200);
        $table->show('create_time', '创建时间')->width(170)->sort(true);
        $table->show('update_time', '更新时间')->width(170)->sort(true);

        //表格右侧操作列
        $table->showRowHandleMenus()->width(130);
        $table->getTableRowBtns()
            ->editBtn(true, '编辑', '98%', '98%')
            ->viewBtn(true, '详情', '98%', '98%')
            ->deleteBtn();

    }

    /**
     * 处理数据
     * 因为查询出来的数据可能需要二次处理
     * @Author   July
     * @DateTime 2024-01-13T19:44:46+0800
     * @param  array   &$data 查询出来的数据
     */
    protected function handleData(&$data = [])
    {

    }

    /**
     * 处理查询条件
     * @Author   July
     * @DateTime 2023-11-16T20:45:54+0800
     * @param array $search  查询条件
     * @return  array $where
     */
    protected function filterWhere($search = [])
    {
        $where = [];

        return $where;
    }

    /**
     * 处理下拉列表查询条件
     * @Author   July
     * @DateTime 2024-01-13T19:47:05+0800
     * @param  array $where  现有的查询条件
     * @return array
     */
    protected function filterSelectPageWhere($where = [])
    {

        return $where;
    }

    /**
     * 处理合计行信息
     * @Author   July
     * @DateTime 2023-11-16T20:45:54+0800
     * @param    array                   $where    已经处理过的最终查询条件，可以自己覆盖，用来自己重新查询数据
     * @param    integer                 $limit    每页多少条
     * @param    string                  $sort     排序
     * @param    integer                 $page     第几页
     * @param    array                   $totalRow 已经查询出来的合计信息，可以自己覆盖返回
     * @return   array                   $totalRow 将处理过的最终信息返回
     */
    protected function filterTotalRow($where = [], $limit = 20, $sort = '', $page = 1, $totalRow = [])
    {
        return $totalRow;
    }

    /**
     * @Author   July
     * @DateTime 2024-01-13T19:49:03+0800
     * @param    Object                   &$form  form对象
     * @param    integer                  $isEdit 是否是编辑：0否，1是
     * @param    array                    &$data  当前这条数据的内容
     */
    protected function buildForm(&$form, $isEdit, &$data = [])
    {
        $AdminRoleLogic = new AdminRoleLogic($this);
        $options        = $AdminRoleLogic->getMenuPermissionsTree();
        cache('permissions' . session('admininfo.id'), $options);
        $permissions_list = $isEdit ? AdminRoleListModel::where(['role_id' => $data['id']])->select()->toArray() : [];
        $permissions      = [];
        foreach ($permissions_list as $k => $v) {
            $permissions[] = '/' . $v['menu_id'] . '/' . $v['module'] . '/' . $v['controller'] . '/' . $v['action'];
        }

        $form->show('text', 'name', '角色名称')->required();
        $form->show('textarea', 'description', '角色描述')->style("height:70px;");
        $form->show('number', 'sort', '排序')->required()->default(0);
        $form->show('switchBtn', 'disabled', '禁用状态')->default(1);
        $form->show('jsTree', 'roles', '权限')->showCheckbox(true)->default($permissions)->setOpen(true)->options($options);
        if ($isEdit) {
            $form->show('html', 'create_time', '创建时间');
            $form->show('html', 'update_time', '更新时间');
        }
    }

    /**
     * 保存
     * @Author   July
     * @DateTime 2023-11-16T20:45:54+0800
     * @param  integer $isEdit 是否是编辑 0否，1是
     */
    protected function save($isEdit)
    {
        $pk = input("get." . $this->getPk());

        $data = request()->only([
            'name',
            'description',
            'sort',
            'disabled',
        ], 'post');

        try {
            validate([
                'name|角色名称' => 'require',
                'sort|排序'   => 'require',
            ])->check($data);
        } catch (\think\exception\ValidateException $e) {
            $this->error($e->getError());
        }
        

        if (!$isEdit) {
            if (!$this->dataModel->save($data)) {
                return json(['code' => 0, 'msg' => '保存失败！']);
            } else {
                $pk = $this->dataModel->id;
            }
        } else {
            $find = $this->dataModel->where([$this->getPk() => $pk])->find();
            if (!$find) {
                return json(['code' => 0, 'msg' => '编辑的数据不存在！']);
            } else {
                $pk = $find['id'];
                if (!$find->save($data)) {
                    return json(['code' => 0, 'msg' => '保存失败！']);
                }
            }
        }


        $roles = array_filter(explode(',', input('post.roles', '')));
        AdminRoleListModel::where(['role_id' => $pk])->delete();
        $role        = [];
        $permissions = cache('permissions' . session('admininfo.id'));
        foreach ($roles as $rk => $rv) {
            $preg = '~([0-9a-zA-Z]+)~';
            preg_match_all($preg, $rv, $res);
            if (isset($res[0])) {
                $preg = '/^(\d+)$/';
                if (preg_match($preg, $rv)) {
                    //如果是菜单id
                    $menu            = MenuModel::find($rv);
                    $menu_parent_ids = MenuModel::getParentIds($rv);
                    $menu_parent_ids = implode(',', $menu_parent_ids);
                    if ($menu) {
                        $role[] = [
                            'menu_id'         => $menu['id'],
                            'role_id'         => $pk,
                            'module'          => $menu['module'],
                            'controller'      => $menu['controller'],
                            'action'          => $menu['action'],
                            'menu_parent_ids' => $menu_parent_ids,
                        ];
                    }
                } else {
                    //如果是权限url
                    $menu_parent_ids = (new MenuModel)->getButtonParentMenuIds($rv, $permissions);
                    $menu_parent_ids = implode(',', $menu_parent_ids);
                    $menu_id         = $res[0][0];
                    $module          = $res[0][1];
                    $controller      = $res[0][2];
                    $action          = $res[0][3];
                    $role[] = [
                        'menu_id'         => $menu_id,
                        'role_id'         => $pk,
                        'module'          => $module,
                        'controller'      => $controller,
                        'action'          => $action,
                        'menu_parent_ids' => $menu_parent_ids,
                    ];
                }
            }
        }

        if ($role) {
            AdminRoleListModel::insertAll($role);
        }

        return $this->doSave($isEdit, $data, $pk);
    }
}
